package com.keekus.common.dto;

import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.List;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeSet;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.util.Assert;

import com.keekus.common.dto.security.Role;

public class User extends BaseDTO{
	protected String id;

	//@Indexed(unique = true)
	//@Size(groups = {PersonValid.class},max = 50,min = 4)
	protected String account;

	protected String firstName;

	protected String lastName;
	
	//@Size(groups = {PersonValid.class},max = 25,min = 4)
	protected String nickName;
	
	//@Digits(groups = {PersonValid.class},integer = 3,fraction = 0)
	protected String age;

	//@NotEmpty(groups = {PersonValid.class})
	//@com.keekus.validator.constrainst.Date(groups = {PersonValid.class},pattern="yyyy/MM/dd")
	protected String birthday;
	
	//@NotEmpty(groups = {PersonValid.class})
	protected String password;

	//@Transient
	//@NotEmpty(groups = {PersonValid.class})
	protected String retypePassword;
	/*@Pattern(regexp = "[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}")*/
	//@NotEmpty(groups = {PersonValid.class})
	//@Email
	protected String email;
	
	//@Transient
	//@NotEmpty(groups = {PersonValid.class})
	protected String verification;


	protected boolean accountEnabled;

	protected boolean accountLocked;

	protected boolean accuontExpired;

	protected boolean credentialsExpired;

	protected Date credentiaExpiredDate;

	//@DBRef
	protected Set<GrantedAuthority> authorities;

	//@DBRef
	protected List<Role> roles;

	public String getRetypePassword() {
		return retypePassword;
	}

	public void setRetypePassword(String retypePassword) {
		this.retypePassword = retypePassword;
	}

	public String getVerification() {
		return verification;
	}

	public void setVerification(String verification) {
		this.verification = verification;
	}

	public boolean isCredentialsExpired() {
		return credentialsExpired;
	}

	public void setCredentialsExpired(boolean credentialsExpired) {
		this.credentialsExpired = credentialsExpired;
	}

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getBirthday() {
		return birthday;
	}

	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}


	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public boolean isAccuontExpired() {
		return accuontExpired;
	}

	public Date getCredentiaExpiredDate() {
		return credentiaExpiredDate;
	}

	public void setCredentiaExpiredDate(Date credentiaExpiredDate) {
		this.credentiaExpiredDate = credentiaExpiredDate;
	}

	public void setAccuontExpired(boolean accuontExpired) {
		this.accuontExpired = accuontExpired;
	}

	public String getAge() {
		return age;
	}

	public List<Role> getRoles() {
		return roles;
	}

	public void setRoles(List<Role> roles) {
		this.roles = roles;
	}

	public void setAge(String age) {
		this.age = age;
	}

	public String getAccount() {
		return account;
	}

	public void setAccount(String account) {
		this.account = account;
	}

	public String getPassword() {
		return password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public boolean isAccountEnabled() {
		return accountEnabled;
	}

	public void setAccountEnabled(boolean accountEnabled) {
		this.accountEnabled = accountEnabled;
	}

	public boolean isAccountLocked() {
		return accountLocked;
	}

	public void setAccountLocked(boolean accountLocked) {
		this.accountLocked = accountLocked;
	}

	public String getNickName() {
		return nickName;
	}

	public void setNickName(String nickName) {
		this.nickName = nickName;
	}

	public Collection<GrantedAuthority> getAuthorities() {
		if (roles == null) {
			return authorities;
		} else {
			SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<GrantedAuthority>(
					new AuthorityComparator());
			if (authorities != null) {
				sortedAuthorities.addAll(authorities);
			}
			for (Role r : roles) {
				sortedAuthorities.addAll(r.getAuthorities());
			}
			return sortedAuthorities;

		}

		// return authorities.add(role.));
	}

	public void setAuthorities(Set<GrantedAuthority> authorities) {
		this.authorities = Collections
				.unmodifiableSet(sortAuthorities(authorities));
	}

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	protected static SortedSet<GrantedAuthority> sortAuthorities(
			Collection<? extends GrantedAuthority> authorities) {
		Assert.notNull(authorities,
				"Cannot pass a null GrantedAuthority collection");
		// Ensure array iteration order is predictable (as per
		// UserDetails.getAuthorities() contract and SEC-717)
		SortedSet<GrantedAuthority> sortedAuthorities = new TreeSet<GrantedAuthority>(
				new AuthorityComparator());
		for (GrantedAuthority grantedAuthority : authorities) {
			Assert.notNull(grantedAuthority,
					"GrantedAuthority list cannot contain any null elements");
			sortedAuthorities.add(grantedAuthority);
		}

		return sortedAuthorities;
	}

	protected static class AuthorityComparator implements
			Comparator<GrantedAuthority>, Serializable {
		public int compare(GrantedAuthority g1, GrantedAuthority g2) {
			if (g2.getAuthority() == null) {
				return -1;
			}
			if (g1.getAuthority() == null) {
				return 1;
			}
			return g1.getAuthority().compareTo(g2.getAuthority());
		}
	}
}
